package com.mes.cotask.manager;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.mes.cotask.manager.iface.ICotaskDetailManager;
import com.mes.cotask.manager.iface.ICotaskManager;
import com.mes.cotask.manager.iface.ISchedulerInteg;
import com.mes.kpi.domain.KPIHeader;
import com.mes.kpi.manager.iface.IKPIHeaderManager;
import com.mes.schedule.domain.ScheduleEvent;
import com.mes.schedule.manager.iface.IScheduleEventManager;
import com.mes.task.dao.iface.IOperationTaskDao;
import com.mes.task.dao.iface.IOperationTaskLinkDao;
import com.mes.task.dao.iface.IPartTaskDao;
import com.mes.task.domain.AssignmentWorkCenter;
import com.mes.task.domain.OperationTask;
import com.mes.task.domain.OperationTaskLink;
import com.mes.task.domain.PartTask;
import com.mes.task.manager.iface.IAssignmentWorkCenterManager;
import com.mes.task.manager.iface.IOperationTaskManager;
import com.mes.task.manager.iface.IPartTaskManager;
import com.mes.cotask.dao.iface.ICotaskDao;
import com.mes.cotask.domain.Cotask;
import com.mes.cotask.domain.CotaskDetail;
import com.mes.basicdata.dao.iface.IRoutingDao;
import com.mes.basicdata.domain.Operation;
import com.mes.basicdata.domain.Routing;
import com.mes.basicdata.domain.RoutingOperation;
import com.mes.basicdata.domain.WorkCenter;
import com.mes.common.manager.BasicManager;
import com.mes.common.util.SysUtil;

@Component
public class CotaskManager extends BasicManager<Cotask> implements ICotaskManager {

	private static final Log logger = LogFactory.getLog(CotaskManager.class);

	@Autowired
	private ICotaskDao cotaskDao;
	@Autowired
	private IPartTaskDao partTaskDao;
	@Autowired
	private IOperationTaskDao operationTaskDao;
	@Autowired
	private IOperationTaskLinkDao operationTaskLinkDao;
	@Autowired
	private IRoutingDao routingDao;
	@Autowired
	private IOperationTaskManager operationTaskManager;
	@Autowired
	private IPartTaskManager partTaskManager;
	@Autowired
	private ICotaskDetailManager cotaskDetailManager;
	@Autowired
	private IAssignmentWorkCenterManager assignmentWorkCenterManager;
	// @Autowired
	// private IKPIHeaderManager kpiHeaderManager;
	@Autowired
	private ISchedulerInteg schedulerInteg;
	@Autowired
	private IScheduleEventManager scheduleEventManager;

	@Override
	@SuppressWarnings("unchecked")
	public boolean isExistByTaskuid(String taskUid) throws Exception {
		return cotaskDao.getCotaskByTaskUid(taskUid) != null ? true : false;
	}

	@Override
	public List<OperationTask> getAllSubTasks(Cotask cotask) throws Exception {
		List<OperationTask> taskList = new LinkedList<OperationTask>();
		String[] taskUids = cotask.getTaskUid().split(",");
		if (taskUids.length != 0) {
			for (int i = 0; i < taskUids.length; i++) {
				OperationTask o = (OperationTask) operationTaskDao.getById(taskUids[i]);
				if (o != null)
					taskList.add(o);
			}
		}
		return taskList;
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	@Override
	public void autoConfirm(Cotask cotask) throws Exception {
		// 首先判断协调次数是否大于3次，大于则设置属性并退出
		if (cotask.getAgreeState() != null && cotask.getAgreeState() == Cotask.STATE_AGREE) {
			// 已经同意，不再协调
			return;
		} else if (cotask.getConsultCount() != null && cotask.getConsultCount() > 3) {
			cotask.setAutoState(Cotask.CONSULT_ARITIFICIAL);// 需要人工干预的任务
			cotask.setNotes("系统协调次数过多，请提交生产处或人工协调！");
			this.addRecord(cotask);
		} else {

			// 获取所有子任务
			List<OperationTask> subTasks = this.getAllSubTasks(cotask);

			// 获取父任务
			PartTask partTask = (PartTask) partTaskDao.getById(cotask.getPartTaskUid());

			// 历史数据信息
			List<OperationTask> historyTask = new LinkedList<OperationTask>();
			Iterator<OperationTask> opItr = subTasks.iterator();
			while (opItr.hasNext()) {
				OperationTask elem = opItr.next();
				historyTask.addAll(cotaskDao.getHistoryTask(elem));
			}

			// 协作任务的工期
			long duration = cotask.getEstiDuration();

			// 前道工序任务
			List<OperationTaskLink> preLinkList = operationTaskLinkDao.findByProperty("succOperationTaskUid",
					subTasks.get(0).getTaskUid());
			OperationTask preOpTask = (preLinkList.isEmpty() ? null : preLinkList.get(0).getSuccOperationTask());

			// 后一道工序
			List<OperationTaskLink> succLinkList = operationTaskLinkDao.findByProperty("predOperationTaskUid",
					subTasks.get(subTasks.size() - 1).getTaskUid());
			OperationTask succOpTask = (succLinkList.isEmpty() ? null : succLinkList.get(0).getPredOperationTask());

			// 统计计算是否同意，同意则不用与调度器沟通，不同意则向调度器发送事件，提交生产处则待定
			double total = 0;
			int t_partFinish = 0;
			int t_critical = 0;
			int t_request = 0;
			int t_esti = 0;
			int t_history = 0;
			int t_consult = 0;
			int t_opDistance = 0;

			long late = partTask.getLateFinish() != null ? partTask.getLateFinish().getTime() : 0;
			long now = new Date().getTime();
			if (late == 0) {
				t_partFinish = 20;
			} else {
				late = (late - now) / (24 * 60 * 60 * 1000);
				if (late < 6) {
					t_partFinish = 100;
				} else if (late < 30) {
					t_partFinish = 80;
				} else if (late < 60) {
					t_partFinish = 50;
				} else {
					t_partFinish = 20;
				}
			}

			int criticalLevel = partTask.getIsCritical() != null ? partTask.getIsCritical() : 0;
			if (criticalLevel < 1) {
				t_critical = 40;
			} else if (criticalLevel < 2) {
				t_critical = 80;
			} else {
				t_critical = 100;
			}

			// 上道工序计划完工时间
			long preTime = (preOpTask != null && preOpTask.getScheduleFinish() != null)
					? preOpTask.getScheduleFinish().getTime() : 0;
			// 本工序计划开始时间
			long preShd = cotask.getScheduleStart() != null ? cotask.getScheduleStart().getTime() : 0;
			// 下道工序计划开始时间
			long succTime = (succOpTask != null && succOpTask.getScheduleStart() != null)
					? succOpTask.getScheduleStart().getTime() : 0;
			// 本工序计划结束时间
			long succShd = cotask.getScheduleFinish() != null ? cotask.getScheduleFinish().getTime() : 0;
			if (preTime == 0 || succTime == 0) {// 没有计划送出和要求返回
				t_request = 20;
			} else {
				long pre = preTime - preShd;
				long suc = succTime - succShd;
				if (0 >= pre && suc >= 0) {
					t_request = 100;
				} else if (pre > 0 && suc >= 0) {
					t_request = 80;
				} else if (0 >= pre && suc < 0) {
					t_request = 50;
				} else {
					t_request = 20;
				}
			}

			if (preTime == 0 || succTime == 0) {// 没有计划送出和要求返回
				t_esti = 10;
			} else if (duration == 0) {
				t_esti = 80;
			} else {
				long conTime = succTime - preTime;
				double rate = conTime / (duration * 24 * 60 * 60 * 1000);
				if (rate >= 1.0) {
					t_esti = 100;
				} else if (rate >= 0.8) {
					t_esti = 70;
				} else if (rate > 0.5) {
					t_esti = 50;
				} else {
					t_esti = 5;
				}
			}

			// 历史数据
			Iterator<OperationTask> itrHis = historyTask.iterator();
			int count = 0;
			double avgHis = 0;
			while (itrHis.hasNext()) {
				OperationTask temp = itrHis.next();
				if (temp.getActualStart() == null || temp.getActualFinish() == null) {
					count++;
					continue;
				} else {
					avgHis += (temp.getActualFinish().getTime() - temp.getActualStart().getTime());
				}
			}
			if ((historyTask.size() - count) > 0) {
				avgHis = avgHis / (historyTask.size() - count);
			}
			if (preTime == 0 || succTime == 0) {// 没有计划送出和要求返回
				t_history = 10;
			} else if (avgHis == 0) {
				t_history = 40;
			} else {
				long conTime = succTime - preTime;
				double rate = conTime / avgHis;
				if (rate >= 1) {
					t_history = 100;
				} else if (rate >= 0.8) {
					t_history = 70;
				} else if (rate >= 0.5) {
					t_history = 30;
				} else {
					t_history = 10;
				}
			}

			long consultCount = cotask.getConsultCount() != null ? cotask.getConsultCount() : 0;
			if (consultCount > 3) {
				t_consult = 0;
			} else if (consultCount > 2) {
				t_consult = 10;
			} else if (consultCount > 1) {
				t_consult = 60;
			} else if (consultCount > 0) {
				t_consult = 80;
			} else {
				t_consult = 100;
			}

			long distance = (subTasks.get(0) != null && subTasks.get(0).getTaskDistance() != null)
					? subTasks.get(0).getTaskDistance() : 0;
			if (distance == 0) {
				t_opDistance = 100;
			} else if (distance < 3) {
				t_opDistance = 80;
			} else if (distance < 6) {
				t_opDistance = 40;
			} else {
				t_opDistance = 0;
			}

			total = t_partFinish * 0.3 + t_critical * 0.15 + t_request * 0.2 + t_esti * 0.15 + t_history * 0.1
					+ t_consult * 0.05 + t_opDistance * 0.05;
			System.out.println("---------------------------->最后总得分：" + total);

			String message = "系统于【" + new Date().toLocaleString() + "】自动协调，最终得分为：" + total;
			if (total > 70 && consultCount < 4) {
				message += "。最终结果： 同意要求！";
				System.out.println("最终结果： 同意要求！");
				// 同意
				cotask.setAgreeState(Cotask.STATE_AGREE);
				cotask.setAutoState(Cotask.CONSULT_AUTO);
				if (preTime > 0) {// 上道工序的计划结束时间不为空
					cotask.setScheduleStart(preOpTask.getScheduleStart());
				}
				if (succTime > 0) {// 下道工序计划开始时间不为空
					cotask.setScheduleFinish(succOpTask.getScheduleFinish());
				}

				// 发送事件
				List<OperationTask> tasks = new LinkedList<OperationTask>();
				tasks.add(this.getAllSubTasks(cotask).get(0));
				schedulerInteg.feedbackCotask(tasks);

			} else if (total > 45 && consultCount < 4) {
				message += "。最终结果：发送协调事件，再次协调。";
				System.out.println("发送协调事件，协调次数加1。");

				// 拒绝，并再次协调。为了模拟车间动态信息，根据协调次数和工期决定计划结束时间。即：协调次数加1，就多加半天工时。
				Date scheduleFinish = cotask.getScheduleFinish();
				scheduleFinish.setTime(
						(long) (scheduleFinish.getTime() + cotask.getConsultCount() * 0.5 * 24 * 60 * 60 * 1000));
				cotask.setScheduleFinish(scheduleFinish);
				cotask.setAgreeState(Cotask.STATE_TO_SENDER);
				cotask.setAutoState(Cotask.CONSULT_AUTO);

				// 发送事件
				List<OperationTask> tasks = new LinkedList<OperationTask>();
				tasks.add(this.getAllSubTasks(cotask).get(0));
				schedulerInteg.feedbackCotask(tasks);

			} else {// 不发送与调度协调的事件，只给出备注和操作记录

				message += "。最终结果：提交生产处或者人工抉择。";
				System.out.println("提交生产处或者人工抉择。");

			}

			cotask.setNotes(message);

			// 添加操作记录
			this.addRecord(cotask);
		}
		this.update(cotask);
	}

	private void addRecord(Cotask cotask) throws Exception {
		ScheduleEvent scheduleEvent = new ScheduleEvent();
		scheduleEvent.setScheduleUid("Cotask-" + new SysUtil().getSessionDeptUid());
		scheduleEvent.setEventType("Auto_Consult");
		scheduleEvent.setKeyUid(cotask.getUuid());
		scheduleEvent.setEventContent("<Cotask cotaskuid='" + cotask.getUuid() + "' mastershop='"
				+ cotask.getMasterShopUid() + "' notes='" + cotask.getNotes() + "' />");
		scheduleEvent.setEventState(ScheduleEvent.EVENTSTATE_DRAFT);
		scheduleEvent.setSourceUid("Cotask-" + new SysUtil().getSessionDeptUid());
		scheduleEvent.setSourceType("系统记录协调信息");
		scheduleEvent.setCreatorUid(SysUtil.getSessionEmployeeUid());
		scheduleEvent.setCreateTime(new Date());

		scheduleEventManager.addScheduleEvent(new SysUtil().getSessionDeptUid(), scheduleEvent);
	}

	public void updateCotaskToScheduler(List<Cotask> cotasks) throws Exception {
		if (cotasks != null) {
			Iterator<Cotask> cotaskItr = cotasks.iterator();
			while (cotaskItr.hasNext()) {
				Cotask temp = cotaskItr.next();
				this.update(temp);
				// 不让调度影响存盘
				try {
					schedulerInteg.feedbackCotask(temp);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		} else {
			throw new Exception("协作任务队列不空！");
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public Cotask generateCotaskByTask(String taskUid) throws Exception {
		OperationTask opTask = (OperationTask) operationTaskDao.getById(taskUid);
		if (opTask == null) {
			throw new Exception("工序任务不存在！taskUid : " + taskUid);
		}
		if (opTask.getMasterShopUid() == null) {
			throw new Exception("工序任务主制车间为空！taskUid : " + taskUid);
		}

		// 首先检查是否存在
		if (this.isExistByTaskuid(opTask.getTaskUid())) {
			return cotaskDao.getCotaskByTaskUid(taskUid);
		}

		// 前后续任务必须与该任务相同
		String parentUid = opTask.getParentTaskUid();

		List<OperationTask> allSubTasks = new LinkedList<OperationTask>();

		OperationTask preOpTask;
		try {
			List<OperationTaskLink> preLinkList = operationTaskLinkDao.findByProperty("succOperationTaskUid",
					opTask.getTaskUid());
			preOpTask = (preLinkList.isEmpty() ? null : preLinkList.get(0).getPredOperationTask());
			// 向上查找同部门的协作任务
			while (preOpTask != null && preOpTask.getMasterShopUid() != null
					&& preOpTask.getMasterShopUid().equals(opTask.getMasterShopUid())
					&& preOpTask.getParentTaskUid().equals(parentUid)) {
				allSubTasks.add(preOpTask);
				List<OperationTaskLink> preLinkListTemp = operationTaskLinkDao.findByProperty("succOperationTaskUid",
						preOpTask.getTaskUid());
				preOpTask = (preLinkListTemp.isEmpty() ? null : preLinkListTemp.get(0).getPredOperationTask());
			}
		} catch (RuntimeException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		allSubTasks.add(opTask);

		try {
			// 向下查找同部门的任务
			List<OperationTaskLink> succLinkList = operationTaskLinkDao.findByProperty("predOperationTaskUid",
					opTask.getTaskUid());
			OperationTask succOpTask = (succLinkList.isEmpty() ? null : succLinkList.get(0).getSuccOperationTask());
			while (succOpTask != null && succOpTask.getMasterShopUid() != null
					&& succOpTask.getMasterShopUid().equals(opTask.getMasterShopUid())
					&& succOpTask.getParentTaskUid().equals(parentUid)) {
				allSubTasks.add(succOpTask);
				List<OperationTaskLink> succLinkListTemp = operationTaskLinkDao.findByProperty("predOperationTaskUid",
						succOpTask.getTaskUid());
				succOpTask = (succLinkListTemp.isEmpty() ? null : succLinkListTemp.get(0).getSuccOperationTask());
			}
		} catch (RuntimeException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		if (allSubTasks.size() > 3) {// 需要排序
			Collections.sort(allSubTasks, new Comparator<OperationTask>() {
				@Override
				public int compare(OperationTask o1, OperationTask o2) {
					return (int) (o1.getOperationId() - o2.getOperationId());
				}
			});
		}

		// 新建协作任务
		Cotask newCotask = new Cotask();
		newCotask.setUuid(SysUtil.getUUID());

		List<CotaskDetail> details = new LinkedList<CotaskDetail>();

		Iterator<OperationTask> opTaskItr = allSubTasks.iterator();
		StringBuilder taskUids = new StringBuilder();
		StringBuilder opUids = new StringBuilder();
		StringBuilder taskNames = new StringBuilder();
		StringBuilder opIdDes = new StringBuilder();
		while (opTaskItr.hasNext()) {
			OperationTask elem = opTaskItr.next();
			taskUids.append(elem.getTaskUid() + ",");
			opUids.append(elem.getOperationUid() + ",");
			taskNames.append(elem.getTaskName() + ",");
			opIdDes.append(elem.getOperationIdDesc() + ",");

			// 检查是否存在
			if (cotaskDetailManager.isExistByTaskUid(elem.getTaskUid())) {
				continue;
			}
			CotaskDetail detail = new CotaskDetail();
			detail.setCoTaskUid(newCotask.getUuid());
			detail.setTaskUid(elem.getTaskUid());
			detail.setCreatorUid(SysUtil.getSessionEmployeeUid());
			detail.setCreateTime(new Date());

			details.add(detail);
		}
		// 去掉最后一位
		taskUids.deleteCharAt(taskUids.length() - 1);
		opUids.deleteCharAt(opUids.length() - 1);
		taskNames.deleteCharAt(taskNames.length() - 1);
		opIdDes.deleteCharAt(opIdDes.length() - 1);

		newCotask.setTaskName(taskNames.toString());
		newCotask.setOperationUid(opUids.toString());
		newCotask.setTaskUid(taskUids.toString());
		newCotask.setOperationIdDesc(opIdDes.toString());
		newCotask.setCreateTime(new Date());
		newCotask.setCreatorUid(SysUtil.getSessionEmployeeUid());
		newCotask.setDeptUid(opTask.getDeptUid());
		newCotask.setMasterShopUid(opTask.getMasterShopUid());
		newCotask.setCotaskState(Cotask.COTASK_STATE_PLANED);
		newCotask.setPartUid(opTask.getPartUid());
		newCotask.setPartTaskUid(opTask.getParentTaskUid());
		newCotask.setPriority(new Long(opTask.getPriority() != null ? opTask.getPriority() : 0));
		newCotask.setBatchNum(opTask.getBatchNum());
		newCotask.setPlanQty(new Long(opTask.getPlanQty() != null ? opTask.getPlanQty().intValue() : 0));
		newCotask.setModel(opTask.getModel());
		// 写上缺省悬挂字段
		newCotask.setSuspended(0l);

		this.add(newCotask);
		cotaskDetailManager.add(details);

		for (OperationTask operationTask : allSubTasks) {
			// 暂时保证即使出错也不影响协作试用
			try {
				this.generateTasksByRoutineTemplate(operationTask);// 通过工艺模板分级协作任务，产生派工的信息
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return newCotask;
	}

	public boolean generateTasksByRoutineTemplate(OperationTask operationTask) throws Exception {
		try {
			logger.error("开始分解任务" + operationTask);
			System.out.println(operationTask.getOperationUid() + "---------------->");
			Operation operation = operationTask.getOperation();// 当前任务的工艺
			if (operation == null || operation.getRefRoutingUid() == null) {// 不能分解
				// throw new Exception("工艺信息缺失！");
				return false;
			} else {
				Routing routing = routingDao.getById(operation.getRefRoutingUid());// 工艺模板
				if (routing == null) {// 模板为空，不能分解
					// throw new Exception("工艺模板信息缺失！");
					return false;
				} else {
					// 工艺详细
					Set<RoutingOperation> routingOperationSet = routing.getRoutingOperations();
					Iterator<RoutingOperation> itrRnOpr = routingOperationSet.iterator();
					// 存储新建子任务
					List<OperationTask> newOperationTaskList = new ArrayList<OperationTask>();
					List<OperationTaskLink> newOperationTaskLinkList = new ArrayList<OperationTaskLink>();
					List<AssignmentWorkCenter> assignmentWorkCenterList = new ArrayList<AssignmentWorkCenter>();

					while (itrRnOpr.hasNext()) {
						RoutingOperation elemRoutingOper = itrRnOpr.next();
						Operation elemOpt = elemRoutingOper.getOperation();

						// 接下来生成新的T_Tasks的子任务，其中Parentuid为当前任务的taskuid
						// opuid为elemOpt的uniqueid,taskname为elemOpt的name,workcenteruid存放elemOpt的machine_number
						// 批次号为elemopt的批次号加上当前任务的工序号，工序号为elemRoutingOper的工序号
						OperationTask newOperationTask = new OperationTask();
						newOperationTask.setParentTaskUid(operationTask.getTaskUid());
						newOperationTask.setTaskUid(SysUtil.getUUID());
						newOperationTask.setOperationUid(elemOpt.getUuid());
						newOperationTask.setTaskName(elemOpt.getOperationName());
						newOperationTask.setWorkCenter(elemOpt.getWorkCenter());
						newOperationTask.setPartUid(operationTask.getPartUid());
						// newOperationTask.setRoutingUid(elemOpt.getRoutingUid());
						newOperationTask
								.setBatchNum(operationTask.getBatchNum() + "_" + operationTask.getOperationIdDesc());
						newOperationTask.setOperationId(elemRoutingOper.getOperationId());
						newOperationTask.setOperationIdDesc(String.valueOf(elemRoutingOper.getOperationId()));
						newOperationTask.setDeptUid(operationTask.getDeptUid());
						newOperationTask.setMasterShopUid(operationTask.getMasterShopUid());
						newOperationTaskList.add(newOperationTask);

						// 向设备派工
						WorkCenter wc = elemOpt.getWorkCenter();

						if (wc != null) // 工作中心
						{
							newOperationTask.setMasterShopUid(wc.getDeptUid());
							newOperationTask.setWorkCenter(wc);

							AssignmentWorkCenter assignmentWorkCenter = new AssignmentWorkCenter();

							assignmentWorkCenter.setOperationTaskUid(newOperationTask.getTaskUid());
							assignmentWorkCenter.setWorkCenterUid(wc.getWorkCenterUid());
							assignmentWorkCenter.setCreatorUid(SysUtil.getSessionEmployeeUid());
							assignmentWorkCenterList.add(assignmentWorkCenter);

						}

					}
					// 添加工序前后关系
					for (int i = 0; i < newOperationTaskList.size() - 1; i++) {
						OperationTaskLink opLink = new OperationTaskLink();
						opLink.setPredOperationTaskUid(newOperationTaskList.get(i).getTaskUid());
						opLink.setSuccOperationTaskUid(newOperationTaskList.get(i + 1).getTaskUid());
						opLink.setLinkType(1);
						opLink.setUuid(SysUtil.getUUID());
						newOperationTaskLinkList.add(opLink);
					}
					operationTaskDao.add(newOperationTaskList);
					operationTaskLinkDao.add(newOperationTaskLinkList);

					assignmentWorkCenterManager.add(assignmentWorkCenterList);

					newOperationTaskList = null;
					newOperationTaskLinkList = null;
					assignmentWorkCenterList = null;

				}

			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return true;
	}

	// /**
	// * @category 计算指标：总任务数，已做计划任务数，准时完成任务数，超期完成任务数，未完成任务数，履约率值计算
	// */
	// @Override
	// public void calculatePerformanceRate() throws Exception {
	// List<Cotask> historyCotasks =
	// cotaskDao.findHistoryCotasksByPrevMonth("00");// 所有部门
	// if (historyCotasks == null) {
	// return;
	// } else {
	// // 按车间分类
	// Set<String> masterShopIds = new HashSet<String>();
	// List<List<Cotask>> cotasksWithDept = new LinkedList<List<Cotask>>();
	//
	// for (Cotask cotask : historyCotasks) {
	// masterShopIds.add(cotask.getMasterShopUid());
	// }
	//
	// // 实例化cotasksWithDept
	// Iterator<String> itrDeptIds = masterShopIds.iterator();
	// while (itrDeptIds.hasNext()) {
	// String deptId = itrDeptIds.next();
	// List<Cotask> tempList = new LinkedList<Cotask>();
	// for (Cotask cotask : historyCotasks) {
	// if (deptId.equals(cotask.getMasterShopUid())) {
	// tempList.add(cotask);
	// }
	// }
	// if (!tempList.isEmpty()) {
	// cotasksWithDept.add(tempList);
	// }
	// }
	//
	// // 按部门分类存储
	// for (List<Cotask> tempList : cotasksWithDept) {
	// this.calAppointedListPf(tempList);
	// }
	// }
	// }

	// @Override
	// public String[] calculateSingleDeptPerformance(String deptUid)
	// throws Exception {
	// List<Cotask> historyCotasks =
	// cotaskDao.findHistoryCotasksByPrevMonth(deptUid);
	// if (!historyCotasks.isEmpty()) {
	// return this.calAppointedListPf(historyCotasks);
	// } else {
	// String[] result = new String[5];
	// for (int i = 0; i < result.length; i++) {// 实例化默认值
	// result[i] = "0";
	// }
	// return result;
	// }
	// }

	// /**
	// * @return String[4] 1:总任务数；2：做计划数；3：超期数；4：惩罚次数；5：协作履约率
	// */
	// private String[] calAppointedListPf(List<Cotask> cotaskList)
	// throws Exception {
	// Date now = new Date();
	// KPIHeader newHeader = new KPIHeader();
	// // 计算过程...notes里面写入总数，计划数，超期数，当月未完成数
	// String kUuid = SysUtil.getUUID();
	// newHeader.setUuid(kUuid);
	// newHeader.setCreateTime(now);
	// newHeader.setDeptUid(cotaskList.get(0).getMasterShopUid());
	// newHeader.setKpiDefinitonId("CotaskPerformanceRate");
	// SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
	// newHeader.setTimeId(format.format(now));
	// newHeader.setCreatorUid(SysUtil.getSessionEmployeeUid());
	// newHeader.setActualCheckTime(now);
	// newHeader.setCheckFromDate(cotaskList.get(0).getScheduleStart());
	// newHeader.setCheckToDate(cotaskList.get(cotaskList.size() - 1)
	// .getScheduleStart());
	// long scheduledCount = 0;
	// long latedCount = 0;// 包括已经完成的和未完成的拖期任务数
	// long punishCount = 0;// 惩罚点数
	// double performanceRate = 0;// 履约率
	// for (Cotask cotask : cotaskList) {
	// if (cotask.getScheduleStart() != null
	// && cotask.getScheduleFinish() != null) {
	// scheduledCount++;
	// }
	//
	// long gap = 0;
	// // 默认5天
	// long days = MMUtils.getProperty("PunishPerDays") != null ? Long
	// .parseLong(MMUtils.getProperty("PunishPerDays")) : 5;
	// long divUom = days * 24 * 60 * 60 * 1000;
	// // 已经完成的任务
	// boolean one = cotask.getPlanFinish() != null
	// && cotask.getCotaskState().equals(
	// Cotask.COTASK_STATE_FINISHED)
	// && cotask.getActualFinish() != null;
	// // 尚未完成的任务,用当前时间考核
	// boolean two = cotask.getPlanFinish() != null
	// && cotask.getCotaskState().equals(Cotask.COTASK_STATE_RECEIVED);
	//
	// if (one || two) {
	// if (one) {
	// gap = cotask.getPlanFinish().getTime()
	// - cotask.getActualFinish().getTime();
	// } else {
	// gap = cotask.getPlanFinish().getTime() - now.getTime();
	// }
	//
	// if (gap < 0) { // 拖期
	// latedCount++;
	// int count = (int) (gap / divUom) + 1;
	// if (cotaskDao.getPriority(cotask) > 3) {// 如果是关键任务，则加倍
	// count *= 2;
	// }
	// punishCount += count;
	// }
	// }
	// }
	// performanceRate = ((cotaskList.size() - latedCount) * 1.0
	// / (cotaskList.size() - latedCount + punishCount) * 1.0) * 100.0;
	// DecimalFormat df = new DecimalFormat();
	// df.setMaximumFractionDigits(2);
	// newHeader.setKpiValue(Double.parseDouble(df.format(performanceRate)));//
	// 两位数精度
	//
	// String[] result = new String[5];
	// result[0] = String.valueOf(cotaskList.size());
	// result[1] = String.valueOf(scheduledCount);
	// result[2] = String.valueOf(latedCount);
	// result[3] = String.valueOf(punishCount);
	// result[4] = String.valueOf(df.format(performanceRate));
	//
	// String notes = "totalCount=" + result[0] + ";scheduledCount="
	// + result[1] + ";latedCount=" + result[2] + ";punishCount="
	// + punishCount + ";performanceRate=" + result[3];
	// newHeader.setNotes(notes);
	//
	// // 存储表头
	// kpiHeaderManager.add(newHeader);
	// //
	// 调用zc的方法，生成快照,参数："t_cotask",kUuid,schedulestart(查找字段),月份Calendar.getInstance().get(Calendar.MONTH)
	//
	// return result;
	// }

	/**
	 * 强制完成协作任务
	 * 
	 * @param cotaskUid
	 *            String
	 * @throws Exception
	 */
	public void forceFinishCotask(String cotaskUid) throws Exception {
		Cotask cotask = cotaskDao.getById(cotaskUid);
		if (cotask == null) {
			throw new Exception("协作任务异常！");
		} else if (cotask.getCotaskState().equals(Cotask.COTASK_STATE_FINISHED)) {
			throw new Exception("任务已经完成！");
		} else {
			cotask.setSuspended(new Long(0));
			cotask.setCotaskState(new Long(3));
			cotask.setCompleteQty(cotask.getPlanQty());
			cotask.setActualFinish(new Date());
			cotask.setNotes("【" + SysUtil.getSessionEmployeeUid() + "】生产处强制完成。");
			if (cotask.getScheduleFinish() != null) {
				cotask.setScheduleFinish(new Date());
			}

			this.update(cotask);
			List<OperationTask> subTasks = this.getAllSubTasks(cotask);

			for (int i = 0; i < subTasks.size(); i++) {
				operationTaskManager.forceFinishTask(subTasks.get(i).getTaskUid(), SysUtil.getSessionEmployeeUid());
			}
		}
	}

	/**
	 * 分批处理,不能static，调用了别的函数。 分批规则更改，这里必须重新开始应用
	 * 
	 * @param partNumber
	 * @param batchnum
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public void splitCotask(String partNumber, String batchnum) throws Exception {
		// 没有记录就返回
		Cotask cotask = cotaskDao.getFirstUncompleteCotask(partNumber, batchnum);
		if (cotask == null) {
			return;
		}

		List<Cotask> changedCotasks = new LinkedList<Cotask>();
		// 所有分批零件任务
		List<PartTask> allPartTasks = partTaskDao.getAllBatchedPartTasks(partNumber, batchnum);
		for (PartTask partTask : allPartTasks) {
			OperationTask firsTask = this.getFirstTask(partTask, cotask);

			if (firsTask != null) {
				Cotask newCotask = this.generateCotaskByTask(firsTask.getTaskUid());

				newCotask.setSenderUid(cotask.getSenderUid());
				newCotask.setActualSend(cotask.getActualSend());
				newCotask.setSendWarehouseUid(cotask.getSendWarehouseUid());
				newCotask.setSendQty(cotask.getSendQty());

				newCotask.setReceiverUid(cotask.getReceiverUid());
				newCotask.setActualReceive(cotask.getActualReceive());
				newCotask.setReceiveWarehouseUid(cotask.getReceiveWarehouseUid());
				newCotask.setReceiveQty(cotask.getReceiveQty());

				newCotask.setEstiDuration(cotask.getEstiDuration());
				newCotask.setAgreeState(cotask.getAgreeState());
				newCotask.setCotaskState(cotask.getCotaskState());
				// 不继承任务的悬挂状态
				// newCotask.setSuspended(cotask.getSuspended());
				newCotask.setSuspended(0l);

				newCotask.setScheduleStart(cotask.getScheduleStart());
				newCotask.setScheduleFinish(cotask.getScheduleFinish());
				newCotask.setActualStart(cotask.getActualStart());
				newCotask.setPlanStart(cotask.getPlanStart());
				newCotask.setPlanFinish(cotask.getPlanFinish());
				newCotask.setPlanQty(partTask.getPlanQty().longValue());

				changedCotasks.add(newCotask);
			} else {
				logger.warn("没有可用的分批信息！cotaskuid:" + cotask.getUuid());
			}
		}

		// 取消原来的主卡,cotaskstate = 8;
		// 判断原来的零件任务是否取消
		PartTask partTask = partTaskManager.getById(cotask.getPartTaskUid());
		if (partTask != null) {
			if (partTask.getTaskState().equals(PartTask.TASKSTATE_CANCELED)) {
				cotask.setCotaskState(new Long(8));
				cotask.setNotes(new SimpleDateFormat("yyyy年MM月dd日").format(new Date()) + "，任务已经取消【原因：分批】");

			} else {
				cotask.setPlanQty(partTask.getPlanQty().longValue());

			}
		}
		changedCotasks.add(cotask);
		this.update(changedCotasks);
	}

	/**
	 * 取到与newPartTask中工序任务对应的第一个协作工序任务
	 * 
	 * @param newPartTask
	 * @param cotask
	 * @return
	 */
	private OperationTask getFirstTask(PartTask newPartTask, Cotask cotask) {
		OperationTask firsTask = null;
		try {
			List<OperationTask> opTasks = operationTaskDao.getUnFinishTasksByPartTask(newPartTask.getTaskUid());

			// 所有协作任务
			List<OperationTask> subs = this.getAllSubTasks(cotask);

			for (OperationTask opTask : opTasks) {
				for (OperationTask operationTask : subs) {
					if (operationTask.getOperationIdDesc().equals(opTask.getOperationIdDesc())) {
						firsTask = opTask;
						break;
					}
				}
				if (firsTask != null)
					break;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("协作错误", e);
		}

		return firsTask;

	}

}
